import 'package:dio/dio.dart';
import 'package:flutter_enjoy_plus/utils/eventbus.dart';
import 'package:flutter_enjoy_plus/utils/token.dart';

class NetworkService {
  final _dio = new Dio();
  // 1.构造函数中，
  // 配置基地址、请求和响应超时时间、请求头
  NetworkService() {
    // 配置基地址
    _dio.options.baseUrl = 'https://live-api.itheima.net/';
    // 配置连接超时时间
    _dio.options.connectTimeout = const Duration(seconds: 10);
    // 配置响应超时时间
    _dio.options.receiveTimeout = const Duration(seconds: 10);
    // 声明拦截器
    _addInterceptors();
  }

  // 2.get和post请求封装
  // get方法，异步封装
  Future get(String url, {Map<String, dynamic>? params}) async {
    try {
      final response = await _dio.get(url, queryParameters: params);
      // 请求成功
      return handleResponse(response);
    } catch (e) {
      // 请求失败
      return handleError(e);
    }
  }

  // post方法，异步封装
  Future post(String url, dynamic data) async {
    try {
      final response = await _dio.post(url, data: data);
      // 请求成功
      return handleResponse(response);
    } catch (e) {
      // 请求失败
      return handleError(e);
    }
  }

  // put方法
  Future<dynamic> put(String url, dynamic data) async {
  try {
    final response = await _dio.put(url, data: data);
    return handleResponse(response);
  } catch (e) {
    return handleError(e);
  }
}
  
  //3. 处理请求成功和失败的结果函数
  // 请求成功
  handleResponse(Response res) {
    if (res.statusCode! >= 200 && res.statusCode! < 300) {
      // 获取成功，数据剥离
      return res.data;
    } else {
      throw Exception('请求失败，状态码${res.statusCode}');
    }
  }

  // 请求失败
  handleError(e) {
    // 如果报错是dio的错误
    if (e is DioException) {
      // 响应超时
      if (e.type == DioExceptionType.connectionTimeout ||
          e.type == DioExceptionType.receiveTimeout) {
        throw Exception('网络请求超时');
      } else if (e.type == DioExceptionType.badResponse) {
        if (e.response?.statusCode == 401) {
          // 401,token失效
          // 1、清除本地token
          TokenManager().removeToken();
          // 2、返回登录页
          eventBus.fire(LogoutEvent());
        } else {
          throw Exception('响应错误，状态码${e.response?.statusCode}');
        }
      } else {
        throw Exception('网络请求错误:$e');
      }
    } else {
      // 报错不是dio的错误
      throw Exception('未知异常$e');
    }
  }

  // 4.封装拦截器,在构造函数中声明
  _addInterceptors() {
    _dio.interceptors.add(
      InterceptorsWrapper(
        // 请求拦截器
        onRequest: (RequestOptions options, RequestInterceptorHandler handler) {
          final token = TokenManager().getToken() ?? '';
          if (token.isNotEmpty) {
            options.headers['Authorization'] = 'Bearer $token';
          }
          return handler.next(options);
        },
        // 响应拦截器
        onResponse: (Response response, ResponseInterceptorHandler handler) {
          return handler.next(response);
        },
        // 错误处理
        onError: (DioException error, ErrorInterceptorHandler handler) {
          return handler.next(error);
        },
      ),
    );
  }
}

final http = NetworkService();
